package com.wangtianxiang.rabbitmq.processor;

import static org.springframework.util.StringUtils.tokenizeToStringArray;

import com.wangtianxiang.rabbitmq.config.DynamicRabbitProperties;
import com.wangtianxiang.rabbitmq.config.RabbitMqProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.autoconfigure.amqp.RabbitRetryTemplateCustomizer;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.ConfigurableApplicationContext;

import java.time.Duration;
import java.util.Map;
import java.util.stream.Collectors;

public class RabbitMqBeanRegister extends BeanRegister{

    private static final Logger logger = LoggerFactory.getLogger(RabbitMqBeanRegister.class);

    // 注册到spring的ConnectionFactory bean后缀
    public static final String BEAN_CONNECTION_FACTORY_SUFFIX = "RabbitConnectionFactory";
    public static final String BEAN_TEMPLATE_SUFFIX = "RabbitTemplate";

    // 注册到spring的RabbitTemplate bean后缀
    public static final String BEAN_RABBIT_TEMPLATE_SUFFIX = "RabbitTemplate";

    private DynamicRabbitProperties dynamicRabbitProperties;

    public RabbitMqBeanRegister(DynamicRabbitProperties dynamicRabbitProperties) {
        this.dynamicRabbitProperties = dynamicRabbitProperties;
    }

    public void registerDatasource(BeanDefinitionRegistry registry, BeanNameGenerator beanNameGenerator){
       /* //配置数据源
        Map<String, RabbitMqProperties> dataSources = dynamicRabbitProperties.getDataSources();
        dataSources.forEach((name,rabbitMqProperties) -> {
            AnnotatedBeanDefinition connectionBeanDefinition = new AnnotatedGenericBeanDefinition(
                    CachingConnectionFactory.class);


            MutablePropertyValues propertyValues = connectionBeanDefinition.getPropertyValues();
            propertyValues.addPropertyValue("host",rabbitMqProperties.getHost());
            propertyValues.addPropertyValue("port",rabbitMqProperties.getPort());
            propertyValues.addPropertyValue("username",rabbitMqProperties.getUsername());
            propertyValues.addPropertyValue("password",rabbitMqProperties.getPassword());
            propertyValues.addPropertyValue("virtualHost",rabbitMqProperties.getVirtualHost());
            propertyValues.addPropertyValue("publisherConfirms",rabbitMqProperties.getPublisherConfirms());
            propertyValues.addPropertyValue("publisherReturns",rabbitMqProperties.getPublisherReturns());

            //alias
            String[] aliasArray = tokenizeToStringArray(rabbitMqProperties.getDataSourceAlias(),
                    ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
            String connectionBeanName = name + BEAN_CONNECTION_FACTORY_SUFFIX;
            String templateBeanName = name + BEAN_TEMPLATE_SUFFIX;
            logger.info("### rabbitMq ### register ConnectionFactory,bean:{}", connectionBeanName);
            if("base".equals(name)){
                connectionBeanDefinition.setPrimary(true);
            }
            //注册rabbitConnection
            BeanDefinitionHolder connectionBeanDefinitionHolder = registerBean(registry, beanNameGenerator, connectionBeanName, aliasArray, connectionBeanDefinition);
            //注册rabbitTemplate
            rabbitTemplateRegister(registry,beanNameGenerator,connectionBeanDefinitionHolder,rabbitMqProperties,templateBeanName);


        });
*/
    }



    public void rabbitTemplateRegister(BeanDefinitionRegistry registry, BeanNameGenerator beanNameGenerator,
                                       BeanDefinitionHolder connectionBeanDefinitionHolder,RabbitMqProperties rabbitMqProperties,String templateBeanName){
     /*   AnnotatedBeanDefinition templateBeanDefinition = new AnnotatedGenericBeanDefinition(
                RabbitTemplate.class);
        templateBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(connectionBeanDefinitionHolder);
        MutablePropertyValues templatePropertyValues = templateBeanDefinition.getPropertyValues();
        templatePropertyValues.addPropertyValue("exchange",rabbitMqProperties.getTemplate().getExchange());
        templatePropertyValues.addPropertyValue("mandatory",rabbitMqProperties.getTemplate().getMandatory());
        try {
            templatePropertyValues.addPropertyValue("confirmCallback",Class.forName(rabbitMqProperties.getConfirmCallback()).newInstance());
        } catch (Exception e) {
            throw new RuntimeException(String.format("confirmCallback create fail class: %s",rabbitMqProperties.getConfirmCallback()),e);
        }
        try {
            templatePropertyValues.addPropertyValue("returnCallback",Class.forName(rabbitMqProperties.getReturnCallback()).newInstance());
        } catch (Exception e) {
            throw new RuntimeException(String.format("returnCallback create fail class: %s",rabbitMqProperties.getReturnCallback()),e);
        }

        PropertyMapper map = PropertyMapper.get();
        MessageConverter messageConverter = this.messageConverter.getIfUnique();
        if (messageConverter != null) {
            template.setMessageConverter(messageConverter);
        }
        template.setMandatory(determineMandatoryFlag());
        RabbitProperties.Template properties = this.properties.getTemplate();
        if (properties.getRetry().isEnabled()) {
            template.setRetryTemplate(new RetryTemplateFactory(
                    this.retryTemplateCustomizers.orderedStream().collect(Collectors.toList())).createRetryTemplate(
                    properties.getRetry(), RabbitRetryTemplateCustomizer.Target.SENDER));
        }
        map.from(properties::getReceiveTimeout).whenNonNull().as(Duration::toMillis)
                .to(template::setReceiveTimeout);
        map.from(properties::getReplyTimeout).whenNonNull().as(Duration::toMillis).to(template::setReplyTimeout);
        map.from(properties::getExchange).to(template::setExchange);
        map.from(properties::getRoutingKey).to(template::setRoutingKey);
        map.from(properties::getDefaultReceiveQueue).whenNonNull().to(template::setDefaultReceiveQueue);

        //注册rabbitTemplate
        registerBean(registry,beanNameGenerator,templateBeanName,null,templateBeanDefinition);*/
    }
}
